/** ****************************************************************************
@addtogroup UltrasonicRanging
@{
*******************************************************************************/

#ifndef _ULTRASONIC_RANGING_H_
#define _ULTRASONIC_RANGING_H_

#include "nonos.h"


// forwards
struct st_driver_ultrasonic_ranging;

/// 当测试到的距离发生变化时回调函数原型定义
typedef void (*FUNC_onUltrasonicRangingChange)(struct st_driver_ultrasonic_ranging* dev, uint32_t distance, void *cookie);

/// 超声波测距模块驱动
typedef struct st_driver_ultrasonic_ranging {
	/// 是否处于监听状态
	uint8_t listen;
	/// 轮询任务 ID
	uint16_t pollTaskId;
	/// 最近一次测试到的距离，单位: cm
	uint16_t distance;
	/// 测试到的距离发生多大的变化时，触发变更事件，单位: 0.01%
	uint16_t deltaRatio;
	/// 多长时间测量一次，单位: ms
	uint32_t pollInterval;
	/// 回波开始时间
	uint32_t echoBeginTime;

	/// TRIG 引脚输出
	FUNC_GPIO_Switch funcTrigSwitch;
	/// ECHO 引脚输入状态
	FUNC_GPIO_IsInOn funcEchoIsOn;

	// 当测试到的距离发生变化时回调
	FUNC_onUltrasonicRangingChange onChange;
	void* cookieChange;
} driver_ultrasonic_ranging_t;

/// @brief 初始化
void ultrasonic_ranging_init(driver_ultrasonic_ranging_t* dev, FUNC_GPIO_Switch funcTrigSwitch, FUNC_GPIO_IsInOn funcEchoIsOn, uint32_t pollInterval, uint16_t deltaRatio);

/// @brief 挂接事件回调函数
void ultrasonic_ranging_setupCallbacks(driver_ultrasonic_ranging_t* dev, FUNC_onUltrasonicRangingChange onChange, void* cookieChange);

/// @brief 监听
void ultrasonic_ranging_listen(driver_ultrasonic_ranging_t* dev, bool enable);

/// @brief 获取当前距离
inline static uint32_t ultrasonic_ranging_getDistance(driver_ultrasonic_ranging_t* dev) {
	return dev ? dev->distance : 0;
}

/// @brief 中断模式：中断处理
/// 应用程序应在 ECHO 引脚对应的 GPIO EXTI 中断中，调用此函数
void ultrasonic_ranging_irqHandler(driver_ultrasonic_ranging_t* dev);


#endif  // _ULTRASONIC_RANGING_H_
/// @}
